package com.atguigu.gmall.mq.listener;

import com.atguigu.gmall.mq.config.DeadLetterConfig;
import com.atguigu.gmall.mq.config.DelayedConfig;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;

/**
 * @author wk
 * @create 2021-09-12 18:02
 * 消息消费方
 */
@Component
public class ConsumerListener {

    @RabbitHandler // 设置手动应答
    @RabbitListener(queues = "testqueue") // 监听队列
    public void receiverMessage(Message message, String msg, Channel channel) {
        System.out.println("消息 从参数中获取：" + msg);
        System.out.println("消息 从消息对象中获取：" + new String(message.getBody()));
        // 手动应答
        // 填写消息的唯一标识 和是否要批量应答 与prefetch相关
        try {
            // 如果出现异常 则消息在队列中会造成阻塞
            int i = 1 / 0;
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            System.out.println("消息标记" + message.getMessageProperties().getDeliveryTag());
        } catch (Exception e) {
            Boolean redelivered = message.getMessageProperties().isRedelivered();
            // 判断是否是生产者重新发送消息
            if (!redelivered) {
                try {
                    // 如果不是重发 那么就尝试重新发送
                    // 参数一：消息的唯一标识
                    // 参数二：是否批量应答
                    // 参数三：是否从队列重新发送
                    System.out.println("第一次发送" + msg);
                    channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            } else {
                // 如果是重发来的消息 则提示队列将该消息删除
                try {
                    System.out.println("第二次发送" + msg);
                    // 参数一：消息的唯一标识
                    // 参数二：不从队列重新发送
                    channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

    @RabbitListener(queues = DeadLetterConfig.queue_dead_2) // 监听队列
    public void receiverDeadMessage(Message message, String msg, Channel channel) {
        System.out.println("消息 从参数中获取：" + msg);
        System.out.println("接收消息的时间" + new Date().getTime());
        // 手动应答
        // 填写消息的唯一标识 和是否要批量应答 与prefetch相关
        // 如果出现异常 则消息在队列中会造成阻塞
        try {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            System.out.println("消息标记" + message.getMessageProperties().getDeliveryTag());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @RabbitListener(queues = DelayedConfig.queue_delay_1) // 监听队列
    public void receiverDelayedMessage(Message message, String msg, Channel channel) {
        System.out.println("消息 从参数中获取：" + msg);
        System.out.println("接收消息的时间" + new Date());
        // 手动应答
        // 填写消息的唯一标识 和是否要批量应答 与prefetch相关
        // 如果出现异常 则消息在队列中会造成阻塞
        try {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            System.out.println("消息标记" + message.getMessageProperties().getDeliveryTag());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
